home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
ACKSRC.ZIP
/
ACKENG.C
< prev
next >
Wrap
Text File
|
1993-06-18
|
21KB
|
700 lines
/**************** ACK-3D ( Animation Construction Kit 3D ) *******************/
/* Engine Code */
/* Author: Lary Myers */
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys\stat.h>
#include "ack3d.h"
#include "ackext.h"
/****************************************************************************
** **
****************************************************************************/
char xRay(int x,int y,int angle)
{
char Color;
int i,j,mx,my;
int TablePosn;
int MapPosn,CurPosn;
int xBeg;
long xPos,xNext;
int BitmapColumn;
int xCenter,yCenter,xAdj;
int ObjPosn;
int oBegX,oBegY;
long yPos;
long yNext;
long xd,yd,sy;
long ObjDist;
xBeg = x & 0xFFC0; /* Get upper left corner of square */
yNext = yNextTable[angle]; /* PreCalc'd value of 64 * Tan(angle) */
if (angle > INT_ANGLE_270 || angle < INT_ANGLE_90)
{
xPos = xBeg + GRID_SIZE; /* Looking to the right */
xNext = GRID_SIZE; /* Positive direction */
}
else
{
xPos = xBeg; /* Looking to the left */
xNext = -GRID_SIZE; /* Negative direction */
yNext = -yNext;
}
/* Calculate the Y coordinate for the current square */
yPos = (((long)xPos - (long)x) * LongTanTable[angle]) + ((long)y << FP_SHIFT);
while (1)
{
if (xPos < 0 || xPos > GRID_XMAX ||
yPos < 0 || yPos > GRID_YMAXLONG)
break;
/************** Fixed point Y/64 * 64 X / 64 ***********/
MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
/* First check for an object that has not been seen yet */
if ((Color = xObjGrid[MapPosn]) > 0 && !(ObjFlags[Color] & 3))
{
ObjFlags[Color] |= 1; /* Indicate object has been seen */
xd = ObjList[Color].x - x;
yd = ObjList[Color].y - y;
ObjDist = (xd * xd) + (yd * yd); /* Calc relative distance */
/* Place the object in the array according to distance, with the ones closer */
/* being drawn last. This will allow closer objects to hide farther objects */
j = TotalObjects;
for (i = 0; i < TotalObjects; i++)
{
if (ObjDist > ObjRelDist[i])
{
for (j = TotalObjects; j > i; j--)
{
ObjRelDist[j] = ObjRelDist[j-1];
ObjNumber[j] = ObjNumber[j-1];
ObjMapPosn[j] = ObjMapPosn[j-1];
}
j = i;
i = TotalObjects;
}
}
/* Hold onto relavant data for the object found */
ObjNumber[j] = Color;
ObjRelDist[j] = ObjDist;
ObjMapPosn[j] = MapPosn;
TotalObjects++;
ObjRelDist[TotalObjects] = 3200000;
}
/* Now check to see if a wall is being struck by the ray */
if ((Color = xGrid[MapPosn]) != 0)
{
xMapPosn = MapPosn; /* Hold onto the map location */
iLastX = xPos;
LastY1 = yPos;
if (Color == DOOR_XCODE) /* Is this a door? */
{
yd = (yPos >> FP_SHIFT) & 0xFFC0; /* Get the left side */
xd = yd + GRID_SIZE; /* And the right side */
ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; /* Calc door distance */
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* Nope, continue casting */
yPos += yNext; /* the ray as before */
continue;
}
LastY1 = yPos + (yNext >> 1); /* Adjust the X,Y values so */
iLastX += (xNext >> 1); /* the door is halfway in sq. */
}
if (Color == DOOR_SECRETCODE)
{
if (xSecretColumn != 0)
{
sy = xSecretColumn * LongTanTable[angle];
ObjDist = (yPos + sy) >> FP_SHIFT;
yd = (yPos >> FP_SHIFT) & 0xFFC0; /* Get the left side */
xd = yd + GRID_SIZE; /* And the right side */
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* Nope, continue casting */
yPos += yNext; /* the ray as before */
continue;
}
LastY1 = yPos + sy;
iLastX += xSecretColumn;
}
}
return(Color);
}
xPos += xNext; /* Next X coordinate (fixed at 64 or -64) */
yPos += yNext; /* Next calculated Y coord for a delta of X */
}
return(0); /* Return that no wall was found */
}
/****************************************************************************
** **
****************************************************************************/
char yRay(int x,int y,int angle)
{
char Color;
int i,j,mx,my;
int MapPosn;
int yBeg;
long yPos,yNext;
int BitmapColumn;
int xCenter,yCenter,yAdj;
int ObjPosn;
int oBegX;
long xPos;
long xNext;
long xd,yd,ObjDist,sx;
yBeg = y & 0xFFC0; /* Same as div 64 then mul 64 */
xNext = xNextTable[angle]; /* Pre-calc'd value of 64 / tan(angle) */
if (angle < INT_ANGLE_180)
{
yPos = yBeg + GRID_SIZE; /* Looking down */
yNext = GRID_SIZE; /* Positive direction */
}
else
{
yPos = yBeg; /* Looking up */
yNext = -GRID_SIZE; /* Negative direction */
xNext = -xNext;
}
/* Calculate the X coordinate for the current square */
xPos = (((long)yPos - (long)y) * LongInvTanTable[angle]) + ((long)x << FP_SHIFT);
oBegX = 0;
while (1)
{
if (xPos < 0 || xPos > GRID_XMAXLONG ||
yPos < 0 || yPos > GRID_YMAX)
break;
/*********** Y/64 * 64 Fixed point and /64 ******/
MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
/* Check for unseen objects first */
if ((Color = yObjGrid[MapPosn]) > 0 && !(ObjFlags[Color] & 3))
{
ObjFlags[Color] |= 2; /* Signal object seen on Y cast */
xd = ObjList[Color].x - x;
yd = ObjList[Color].y - y;
yd = (xd * xd) + (yd * yd); /* Calc relative distance to object */
/* Place the object in the array according to distance, with the ones closer */
/* being drawn last. This will allow closer objects to hide farther objects */
j = TotalObjects;
for (i = 0; i < TotalObjects; i++)
{
if (yd > ObjRelDist[i])
{
for (j = TotalObjects; j > i; j--)
{
ObjRelDist[j] = ObjRelDist[j-1];
ObjNumber[j] = ObjNumber[j-1];
ObjMapPosn[j] = ObjMapPosn[j-1];
}
j = i;
i = TotalObjects;
}
}
ObjNumber[j] = Color; /* Hold onto object data for later */
ObjRelDist[j] = yd;
ObjMapPosn[j] = MapPosn;
TotalObjects++;
ObjRelDist[TotalObjects] = 3200000;
}
/** Check for a wall being struck **/
if ((Color = yGrid[MapPosn]) != 0)
{
yMapPosn = MapPosn; /* Hold onto map position */
LastX1 = xPos;
iLastY = yPos;
if (Color == DOOR_YCODE) /* Is this a door? */
{
yd = (xPos >> FP_SHIFT) & 0xFFC0; /* Calc top side of square */
xd = yd + GRID_SIZE; /* And bottom side of square */
ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* No, continue on with ray cast */
yPos += yNext;
continue;
}
LastX1 = xPos + (xNext >> 1); /* Adjust coordinates so door is */
iLastY += (yNext >> 1); /* Halfway into wall */
}
if (Color == DOOR_SECRETCODE)
{
if (ySecretColumn != 0)
{
sx = ySecretColumn * LongInvTanTable[angle];
ObjDist = (xPos + sx) >> FP_SHIFT;
yd = (xPos >> FP_SHIFT) & 0xFFC0; /* Get the top side */
xd = yd + GRID_SIZE; /* And the bottom side */
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* Nope, continue casting */
yPos += yNext; /* the ray as before */
continue;
}
LastX1 = xPos + sx;
iLastY += ySecretColumn;
}
}
return(Color);
}
xPos += xNext; /* Next calculated X value for delta Y */
yPos += yNext; /* Next fixed value of 64 or -64 */
if (++oBegX > 64) /* Check a maximum number of squares */
break;
}
return(0); /* Return here if no Y wall is found */
}
/********************************************************